home *** CD-ROM | disk | FTP | other *** search
- /* Keyboard routines and menus for VRC release */
-
- /* Original simple keyboard was written by Bernie Roehl, July 1992 */
-
- // MASSIVELY rewritten, along with entire menu and navigation
- // system, by Dave Stampe for Release 5 (VRC), Nov. 92.
-
- // some changes made to support horizon and key monitor, 12/24/93
-
- // Completely rearranged, substantial mods, ported to VR-386 API 9/1/94
-
-
- /*
- This code is part of the VR-386 project, created by Dave Stampe.
- VR-386 is a desendent of REND386, created by Dave Stampe and
- Bernie Roehl. Almost all the code has been rewritten by Dave
- Stampre for VR-386.
-
- Copyright (c) 1994 by Dave Stampe:
- May be freely used to write software for release into the public domain
- or for educational use; all commercial endeavours MUST contact Dave Stampe
- (dstampe@psych.toronto.edu) for permission to incorporate any part of
- this software or source code into their products! Usually there is no
- charge for under 50-100 items for low-cost or shareware products, and terms
- are reasonable. Any royalties are used for development, so equipment is
- often acceptable payment.
-
- ATTRIBUTION: If you use any part of this source code or the libraries
- in your projects, you must give attribution to VR-386 and Dave Stampe,
- and any other authors in your documentation, source code, and at startup
- of your program. Let's keep the freeware ball rolling!
-
- DEVELOPMENT: VR-386 is a effort to develop the process started by
- REND386, improving programmer access by rewriting the code and supplying
- a standard API. If you write improvements, add new functions rather
- than rewriting current functions. This will make it possible to
- include you improved code in the next API release. YOU can help advance
- VR-386. Comments on the API are welcome.
-
- CONTACT: dstampe@psych.toronto.edu
- */
-
- #include <stdio.h>
- #include <stdlib.h> /* for atol(), only for debugging! */
- #include <dos.h>
- #include <time.h> /* time(), ctime() */
- #include <string.h>
- #include <math.h>
- #include <alloc.h>
-
- #include "config.h"
- #include "pointer.h"
- #include "vr_api.h"
- #include "intmath.h"
- #include "segment.h"
- #include "splits.h"
- #include "pcdevice.h" // last_render_time()
- #include "vrconst.h"
-
- extern char *fix_fname(char *fname);
-
- extern manip_2D_avail;
-
- extern void set_horizon(int ncolors, int colors[16], int bandsize);
-
- extern int do_screen_clear, do_horizon;
- extern int show_location, show_compass, show_framerate;
-
- extern LIGHT *amb_light, *light1, *light2;
-
- static int sstepsize = 10; /* speed multipliers */
- static int astepsize = 2;
-
- long anglestep = 160000L;
- long spacestep = 10L;
-
- int spinmode = 0;
- extern int flymode;
- int floormode = 0;
- extern int animatemode;
-
- extern int old_angle_order; /* in wparse.c */
-
- /******************* MENU TEXT **************/
-
- static char *helptext[] = {
- "X calls up MAIN MENU",
- "O calls up OBJECT MENU",
- "P calls up PAINT MENU",
- "F calls up FIGURE MENU",
- "V calls up VIEW MENU",
- "M calls up MANIPULATE MENU",
- "D calls up DISPLAY OPTIONS MENU",
- "ARROWS drive around",
- "RIGHT SHIFT+ARROWS look around",
- "LEFT SHIFT+ARROWS move up, sideways",
- "CTRL+ARROWS set stereo offset",
- "J toggles mouse motion, U u-turns",
- "+ and - changes zoom",
- "R repeats last arrow key move 100x",
- "0-9 set step or angle size",
- "F1-F10 select viewpoint",
- "HOME returns to starting point",
- "Q or ESC quits, ? or H shows help",
- "I displays view information",
- "S sets/resets object spin mode",
- "C displays color palette",
- "A toggles animation on/off",
- NULL
- };
-
- static char *mainmenu[] = {
- "Help",
- "Information",
- "View menu",
- "Paint menu",
- "Display menu",
- "Object menu",
- "Figure menu",
- "Mouse menu",
- "Quit",
- NULL
- };
-
- static char *viewmenu[] = {
- "Information",
- "Spin about object",
- "Fly mode toggle",
- "fLoor mode toggle",
- "Return to start",
- "Move step size",
- "Turn step set",
- "Go to (x,y,z) location",
- "look Angle ",
- "View window size",
- "Hither clipping depth",
- "Yon clipping depth",
- "PCX screen dump",
- "Options",
- #ifdef ENABLE_STATE_SAVELOAD
- "Write state to file",
- "eXecute world file",
- #endif
- NULL
- };
-
- static char *paintmenu[] = {
- "Select Surface",
- "Choose Color",
- "Get poly color",
- "Paint Polys",
- "paint All",
- "Resurface",
- NULL
- };
-
- static char *surfmenu[] = {
- "Absolute",
- "Cosine-lit",
- "Metal",
- "Glass",
- NULL
- };
-
- static char *optmenu[] = {
- "aniMation on/off",
- "Screen clear",
- "Horizon",
- "Ambient light",
- "Directional light",
- "Position display",
- "Compass display",
- "Frame rate display",
- NULL };
-
- static char *mousemenu[] = {
- "Move",
- "Rotate",
- "Twirl",
- "Grasp",
- "Ungrasp",
- NULL
- };
-
- static char *objmenu[] = {
- "Load object",
- "Save object",
- "Information",
- "Delete object",
- "Unselect all",
- "First representation",
- "Next representation",
- NULL
- };
-
- static char *figmenu[] = {
- "Load figure",
- "Information",
- "Select all",
- "Unselect all",
- "Hack off",
- "Join to",
- "Attach viewpoint",
- "Detach viewpoint",
- NULL
- };
-
-
-
- /*************** MORE FEATURES *************/
-
- static int save_pcx_file(void)
- {
- char filename[100];
- char far *buffer;
- FILE *out;
- BOOL was_visible;
-
- screen_refresh(current_camera);
- askfor("File to save to? ", filename, 15);
- if (filename[0] == '\0') return 1;
- if ((out = fopen(filename, "wb")) == NULL)
- {
- errprintf("Could not open file");
- cursor_show();
- return 3;
- }
- was_visible = cursor_hide();
- save_pcx(out, current_video_page);
- if(was_visible) cursor_show();
- fclose(out);
- return 0;
- }
-
-
-
- extern PDRIVER *cursor_device;
-
- static int resize_viewport(void)
- {
- int top, left, bottom, right;
- unsigned buttons;
-
- if(stereo_type!=MONOSCOPIC && stereo_type!= SWITCHED) return -1;
-
- save_screen();
-
- popmsg("Click top-left and drag");
-
- cursor_show();
- do {
- move_2D(cursor_device, &left, &top, &buttons);
- if(kbhit())
- {
- getch();
- screen_refresh(current_camera);
- return 1;
- }
- } while (buttons == 0);
-
- while (buttons)
- {
- while (!move_2D(cursor_device, &right, &bottom, &buttons));
- restore_screen();
- user_draw_box(left, top, right, bottom, 15);
- }
- cursor_hide();
-
- if (right - left > 10)
- {
- left = left & (~0x0007); /* always on an 8-pixel boundary */
- right = (right & (~0x0007)) + 7;
- }
- else return -1;
-
- if (bottom - top < 10) return -1;
- set_camera_window(current_camera, left, top, right, bottom);
-
- if (stereo_type == SWITCHED) /* makes sense for Sega only (no shift) */
- {
- STEREO *s = current_camera->stereo;
- s->pixel_width = right-left+1;
- s->window[LEFT_EYE].l = left;
- s->window[LEFT_EYE].t = top;
- s->window[LEFT_EYE].r = right;
- s->window[LEFT_EYE].b = bottom;
- s->window[RIGHT_EYE].l = left;
- s->window[RIGHT_EYE].t = top;
- s->window[RIGHT_EYE].r = right;
- s->window[RIGHT_EYE].b = bottom;
- }
-
- compute_camera_factors(current_camera);
-
- display_changed++;
- cursor_hide();
- reset_screens();
- return 0;
- }
-
-
-
-
- /*************** STATUS DISPLAYS ETC. ************/
-
-
-
- static void center(char *s, int w) // centers text string
- {
- int n;
-
- if (strlen(s) == 0) return;
- n = (w - strlen(s)) /2;
- memmove(&s[n], s, strlen(s)+1);
- memset(s, ' ', n);
- }
-
- static int nobjs, nverts, npolys;
-
- static void gather_data(OBJECT *obj)
- {
- int nv = 0, np = 0;
-
- get_obj_info(obj, &nv, &np);
- ++nobjs;
- nverts += nv;
- npolys += np;
- }
-
-
- static disp_status(POSE *p)
- {
- char *text[10], a[80], b[80], c[80], d[80], e[80], f[80], g[80], h[80];
- int w, i;
- VIEW *v = current_camera->mono;
-
- text[0] = a;
- text[1] = "";
- text[2] = b;
- text[3] = c;
- text[4] = d;
- text[5] = e;
- text[6] = f;
- text[7] = g;
- text[8] = h;
- text[9] = NULL;
- sprintf(a, "STATUS");
-
- sprintf(b, "X = %ld Y = %ld Z = %ld", p->x, p->y, p->z);
- w = strlen(b);
-
- if (old_angle_order)
- sprintf(c, "Pan = %ld Tilt = %ld Roll = %ld ", p->ry/65536L, p->rx/65536L, p->rz/65536L);
- else
- sprintf(c, "Tilt = %ld Pan = %ld Roll = %ld ", p->rx/65536L, p->ry/65536L, p->rz/65536L);
- if (strlen(c) > w) w = strlen(c);
- sprintf(d, "Zoom = %2.2f", scale2float(get_camera_zoom(current_camera)));
- if (strlen(d) > w) w = strlen(d);
- sprintf(e, "Hither = %ld Yon = %ld", get_camera_hither(current_camera), get_camera_yon(current_camera));
- if (strlen(e) > w) w = strlen(e);
-
- nobjs = 0, nverts = 0, npolys = 0;
- do_for_all_objects(gather_data);
- sprintf(f, "%d object%s, %d vertice%s, %d poly%s",nobjs,(nobjs == 1) ? "" : "s",
- nverts, (nverts == 1) ? "" : "s",
- npolys, (npolys == 1) ? "" : "s");
-
- sprintf(g, "Ambient light: %d", get_light_intensity(amb_light));
-
- sprintf(h, "Memory Free: %ld", coreleft());
-
- if (strlen(f) > w) w = strlen(f);
- if (strlen(g) > w) w = strlen(g);
- if (strlen(h) > w) w = strlen(h);
-
- for (i = 0; text[i]; ++i) center(text[i], w);
-
- save_screen();
- poptext(text);
- return 0;
- }
-
-
- void disp_palette(void) // show 256-color palette
- {
- int i, j;
- BOOL was_visible = cursor_hide();
-
- save_screen();
- for (i = 0; i < 16; i++)
- for (j = 0; j < 16; j++)
- user_box(j*10,i*8,j*10+9,i*8+8,i*16+j);
- if(was_visible) cursor_show();
- }
-
-
- /*************** VIEW MENU *************/
-
- void process_a_key(WORD key);
-
- static void view_menu(void)
- {
- char buff[100], *p;
- FILE *out;
- char d;
- COORD l;
-
- save_screen();
- switch (menu(viewmenu))
- {
- case 'I':
- process_a_key('I');
- break;
- case 'R':
- process_a_key (HOME);
- position_changed++;
- break;
- case 'P':
- process_a_key('^');
- break;
- case 'F':
- flymode = !flymode;
- popmsg(flymode ? "Fly mode" : "Ground mode");
- tdelay(350);
- break;
- case 'L':
- floormode = !floormode;
- popmsg(floormode ? "Floors used" : "Floors ignored");
- tdelay(350);
- break;
- case 'H':
- askfor("Enter hither value:", buff, 10);
- if (buff[0])
- {
- COORD h = atof(buff);
- set_camera_hither(current_camera, h);
- }
- display_changed++;
- break;
- case 'Y':
- askfor("Enter yon value:", buff, 10);
- if (buff[0])
- {
- COORD y = atof(buff);
- set_camera_yon(current_camera, y);
- }
- display_changed++;
- break;
- case 'G':/* goto XYZ */
- askfor("X,Y,Z: ", buff, 25);
- if (buff[0])
- sscanf(buff, "%ld,%ld,%ld", &body_pose->x, &body_pose->y, &body_pose->z);
- position_changed++;
- break;
- case 'A':/* look at angle */
- {
- long p, t, r;
- askfor("Pan,rx,rz:", buff, 22);
- if (buff[0])
- {
- sscanf(buff, "%ld,%ld,%ld", &p, &t, &r);
- body_pose->ry = p*65536L;
- body_pose->rx = t*65536L;
- body_pose->rz = r*65536L;
- }
- position_changed++;
- }
- break;
- case 'M':
- askfor("Move step: ", buff, 15);
- if (buff[0]) spacestep = atoi(buff);
- position_changed++;
- break;
- case 'T':
- askfor("Turn angle step: ", buff, 15);
- if (buff[0]) anglestep = atof(buff) * 65536L;
- position_changed++;
- break;
- case 'V':
- resize_viewport();
- display_changed++;
- break;
- case 'O':
- disp_options();
- break;
- case 'S':
- process_a_key('S');
- break;
- default:
- break;
- }
- restore_screen();
- }
-
-
- static void stereo_info(void)
- {
- char b1[50]="", b2[50]="", b3[50]="", b4[50]="", b5[50]="", b6[50]="";
- char b7[50]="", b8[50]="", b9[50]="";
- char *b[10];
- STEREO *st = current_camera->stereo;
- STWINDOW *swl = &(current_camera->stereo->window[LEFT_EYE]);
- STWINDOW *swr = &(current_camera->stereo->window[RIGHT_EYE]);
- float xo, xa, conv, ws;
-
- if(stereo_type==MONOSCOPIC) return;
-
- xa = (swl->xoff-swr->xoff)/2.0;
- ws = st->world_scaling/65536.0;
- xo=(st->phys_eye_spacing * st->phys_screen_dist * st->pixel_width) /
- (2.0 * st->phys_screen_width * st->phys_convergence);
- conv=(st->phys_eye_spacing * st->phys_screen_dist * st->pixel_width) /
- (2.0 * st->phys_screen_width * (xo+xa));
-
- b[0] = b1;
- sprintf(b1, " Stereo Parameters");
- b[1] = b2;
- sprintf(b2, "screen distance: %ld", st->phys_screen_dist);
- b[2] = b3;
- sprintf(b3, "screen width: %ld", st->phys_screen_width);
- b[3] = b4;
- sprintf(b4, "pixel width: %ld", st->pixel_width);
- b[4] = b5;
- sprintf(b5, "eye spacing: %ld", st->phys_eye_spacing);
- b[5] = b6;
- sprintf(b6, "convergence distance: %ld", st->phys_convergence);
- b[6] = b7;
- sprintf(b7, "world scaling: %0.2f", ws);
- b[7] = b8;
- sprintf(b8, "added X offset: %0.0f", xa);
- b[8] = b9;
- sprintf(b9, "effective convergence: %0.0f", conv);
- b[9] = NULL;
-
- save_screen();
- poptext(b);
- get_response(1);
- restore_screen();
- }
-
-
- /************* PROCESS SUPPORT ***********/
-
- static int nselected = 0;
-
- static FILE *save_file = NULL;
-
- static int nsaved = 0;
-
- static void save_it(OBJECT *obj)
- {
- if(nselected<2) save_plg(obj, save_file, 0); /* only one: save object coords */
- else save_plg(obj, save_file, 1); /* else save world coords */
- }
-
- static long mxosize = 0;
-
- static void maxsize_it(OBJECT *obj) // find maximum size of figure
- {
- long s;
- if(obj)
- {
- s = get_object_bounds(obj, NULL, NULL, NULL);
- if(s>mxosize) mxosize = s;
- }
- }
-
-
- static int numsegs, numverts, numpolys;
- static long centx, centy, centz;
- static OBJECT *last_figure; // last moveable and visible
- // object (split list)
-
- static void count_moveable(OBJECT *obj)
- {
- ++nselected;
- get_object_bounds(obj, ¢x, ¢y, ¢z);
- if(is_object_moveable(obj))
- {
- int nv, np;
- get_obj_info(obj, &nv, &np);
- numverts += nv;
- numpolys += np;
- last_figure = obj;
- numsegs++;
- }
- }
-
-
- static void count_all(OBJECT *obj)
- {
- int nv, np;
- get_object_bounds(obj, ¢x, ¢y, ¢z);
- get_obj_info(obj, &nv, &np);
- numverts += nv;
- numpolys += np;
- nselected++;
- }
-
-
-
- static void zap_obj(OBJECT *obj)
- {
- delete_visobj(obj); // preserve segment so animation doesnt crash
- }
-
-
- extern OBJECT *body_seg;
- extern OBJECT *head_seg;
- extern OBJECT *wrist_seg;
-
-
- static void grab_it(OBJECT *obj) // attach to body
- {
- if(is_object_child_of(body_seg, obj)) return; // can't grab body part!
- attach_object(obj, body_seg, 1);
- }
-
-
- static void ungrab_it(OBJECT *obj) // detach from body
- {
- if(is_object_child_of(body_seg, obj))
- detach_object(obj,1);
- }
-
-
- //////// MOVEMENT CALLBACKS
-
- static long ptx, pty, ptz;
- static long oldx, oldy, oldz, oldcx, oldcy, oldcz, dx, dy, dz;
-
- static void move_it(OBJECT *obj)
- {
- if(is_object_moveable(obj))
- {
- POSE p;
- get_object_pose(obj, &p);
- p.x += ptx - oldx;
- p.y += pty - oldy;
- p.z += ptz - oldz;
- p.rx = p.ry = p.rz = DONTCARE;
- set_object_pose(obj, &p);
- update_object(obj);
- }
- }
-
- static void twirl_it(OBJECT *obj)
- {
- if(is_object_moveable(obj))
- {
- POSE p;
- get_object_pose(obj, &p);
- p.rx += ptx;
- p.ry += pty;
- p.rz += ptz;
- p.x = p.y = p.z = DONTCARE;
- set_object_pose(obj, &p);
- update_object(obj);
- }
- }
-
- static void rot_it(OBJECT *obj)
- {
- if(is_object_moveable(obj))
- {
- POSE p;
- get_object_pose(obj, &p);
- p.rx += ptx;
- p.ry += pty;
- p.rz += ptz;
- p.x = p.y = p.z = DONTCARE;
- set_object_pose(obj, &p);
- update_object(obj);
- }
- }
-
-
- static void hack_it(OBJECT *obj)
- {
- if(is_object_moveable(obj))
- {
- detach_object(obj, 1);
- update_object(obj);
- }
- }
-
-
- static OBJECT *newparent = NULL;
-
- static void join_it(OBJECT *obj)
- {
- if(is_object_moveable(obj))
- {
- attach_object(obj, newparent, 1);
- update_object(obj);
- }
- }
-
-
- static void next_it(OBJECT *obj)
- {
- select_next_representation(obj);
- }
-
-
- static void first_it(OBJECT *obj)
- {
- select_first_representation(obj);
- }
-
-
- static int check_moveobj(void)
- {
- nselected = 0;
- last_figure = NULL;
-
- do_for_all_selected_moveable(count_moveable);
- if (last_figure == NULL)
- {
- popmsg("No movable objects selected!");
- tdelay(600);
- return 1;
- }
- return 0;
- }
-
-
- static int check_obj(void)
- {
- nselected = 0;
- last_figure = NULL;
-
- do_for_all_selected(count_moveable);
- if (nselected == 0)
- {
- popmsg("No objects selected!");
- tdelay(600);
- return 1;
- }
- return 0;
- }
-
- static void seg_info(int fig)
- {
- char b1[50]="", b2[50]="", b3[50]="", b4[50]="", b5[50]="", b6[50]="";
- char *b[7];
- POSE p;
-
- b[0] = b1;
- b[1] = b2;
- b[2] = b3;
- b[3] = b4;
- b[4] = b5;
- b[5] = b6;
- b[6] = NULL;
- nselected = 0;
- last_figure = NULL;
- do_for_all_selected(count_moveable);
- sprintf(b6, "Object center:%ld, %ld, %ld", centx, centy, centz);
- nobjs = nverts = npolys = 0;
- if(fig && last_figure)
- {
- numsegs = numverts = numpolys = 0;
- do_for_selected_related_objects(last_figure, count_moveable);
- sprintf(b1, "%d seg%s, %d vert%s, %d poly%s",
- numsegs, (numsegs == 1) ? "" : "s",
- numverts, (numverts == 1) ? "" : "s",
- numpolys, (numpolys == 1) ? "" : "s" );
- }
- else
- {
- nselected = numverts = numpolys = 0;
- do_for_all_selected(count_all);
- sprintf(b1, "%d obj%s, %d vert%s, %d poly%s",
- nselected, (nselected == 1) ? "" : "s",
- numverts, (numverts == 1) ? "" : "s",
- numpolys, (numpolys == 1) ? "" : "s" );
- }
- if(last_figure==NULL)
- {
- sprintf(b2," No moveable objects selected");
- b[2] = b6;
- b[3] = NULL;
- }
- else
- {
- get_object_world_pose(last_figure, &p);
- sprintf(b2, "World pos'n: %ld %ld %ld", p.x, p.y, p.z);
- sprintf(b3, "World angle: %4.1f %4.1f %4.1f", angle2float(p.rx), angle2float(p.ry),angle2float(p.rz));
- if(last_figure==NULL || fig==0)
- {
- get_object_pose(last_figure, &p);
- sprintf(b4, "Joint pos'n: %ld %ld %ld", p.x, p.y, p.z);
- sprintf(b5, "Joint angle: %4.1f %4.1f %4.1f", angle2float(p.rx), angle2float(p.ry),angle2float(p.rz));
- }
- else
- {
- b[4] = b6;
- b[3] = b[2];
- b[2] = b[1];
- b[5] = NULL;
- sprintf(b5,"Root of figure:");
- b[1] = b5;
- }
- }
- poptext(b);
- }
-
-
-
- /************* MOUSE MANIPULATION MENU ***********/
-
- extern PDRIVER *cursor_device;
-
- static POINTER pointer;
-
- static void mouse_menu(void)
- {
- void pointer_to_world();
- char buff[100], *p;
- char c, d;
- unsigned buttons;
- int click = 0;
-
- init_pointer(&pointer);
-
- save_screen();
- switch(c = menu(mousemenu))
- {
- case 'M':
- restore_screen();
- if(check_moveobj()) break;
- if (!manip_2D_avail) break;
- pointer_read(cursor_device, &pointer);
- pointer_to_world(&pointer, current_camera, &ptx, &pty, &ptz);
- click = 0;
- while (click == 0)
- {
- screen_refresh(current_camera);
- oldx = ptx;
- oldy = pty;
- oldz = ptz;
- click = PNEW_BUT & pointer_read(cursor_device, &pointer);
- if (!(pointer.buttons & 1)) click = 0;
- pointer_to_world(&pointer, current_camera, &ptx, &pty, &ptz);
- do_for_all_selected_moveable(move_it);
- }
- screen_refresh(current_camera);
- world_changed++;
- break;
- case 'R':
- case 'T':
- restore_screen();
- if(check_moveobj()) break;
- if (!manip_2D_avail) break;
- pointer_read(cursor_device, &pointer);
- oldcx = oldx = pointer.x;
- oldcy = oldy = pointer.y;
- oldcz = oldz = pointer.z;
- while ((pointer.buttons & 0x01) == 0)
- {
- if (toupper(c) == 'R')
- {
- ptx = 32768L*(pointer.y - oldy);
- pty = -32768L*(pointer.x - oldx);
- ptz = -32768L*(pointer.z - oldz);
- }
- else
- {
- ptx = 3270L*(pointer.y - oldcy);
- pty = -3270L*(pointer.x - oldcx);
- ptz = -3270L*(pointer.z - oldcz);
- }
- rotate_to_view(current_camera, &ptx, &pty, &ptz);
- if(toupper(c)=='R') do_for_all_selected_moveable(rot_it);
- else do_for_all_selected_moveable(twirl_it);
- oldx = pointer.x;
- oldy = pointer.y;
- oldz = pointer.z;
- screen_refresh(current_camera);
- pointer_read(cursor_device, &pointer);
- }
-
- while (pointer.buttons & 0x01) pointer_read(cursor_device, &pointer);
- screen_refresh(current_camera);
- world_changed++;
- break;
- case 'G':
- if(check_moveobj()) break;
- do_for_all_selected_moveable(grab_it);
- world_changed++;
- break;
- case 'U':
- if(check_moveobj()) break;
- do_for_all_selected_moveable(ungrab_it);
- world_changed++;
- break;
- default:
- break;
- }
- restore_screen();
- }
-
-
-
-
- static int obj_menu(void)
- {
- char buff[100], *p;
- FILE *in, *out;
- char c, d;
- long x, y, z;
- int i;
-
- nselected = 0;
- last_figure = NULL;
-
- save_screen();
- switch (c=menu(objmenu))
- {
- case 'L':/* load PLG file */
- askfor("File to load? ", buff, 22);
- if (buff[0] == '\0') break;
- strcpy(buff, fix_fname(buff));
- add_ext(buff,"plg");
- if ((in = fopen(buff, "r")) == NULL)
- {
- errprintf("Could not open file");
- }
- else
- {
- POSE p = ZERO_POSE;
- OBJECT *obj;
- long sx = 1, sy = 1, sz = 1;
- #ifdef ENABLE_RESIZE_ON_LOAD
- askfor("Scale x,y,z: ", buff, 20);
- if (buff[0])
- sscanf(buff, "%ld,%ld,%ld", &sx, &sy, &sz);
- #endif
-
- while ((obj = load_plg_object(in, &p, 1, 1, 1, 0)) != NULL)
- {
- if (make_fixed_object_moveable(obj,NULL)) // moveable object
- { // now put nicely ahead
- mxosize = 0;
- do_for_visible_child_objects(obj, maxsize_it);
- camera_point_ahead(current_camera, 500+mxosize*4, &p.x, &p.y, &p.z);
- set_object_pose(obj, &p);
- update_object(obj);
- add_object_to_world(obj); // adds to world if not in it
- }
- else
- {
- errprintf("Warning -- out of memory!");
- world_changed++;
- }
- }
- fclose(in);
- }
- world_changed++;
- break;
-
- case 'S':
- restore_screen();
- if(check_obj()) break;
- if (askfor("Enter filename: ", buff, 20) == 0x1B) break;
- if (buff[0] == '\0')
- {
- world_changed++;
- break;
- }
- nobjs = 0;
- add_ext(buff,"plg");
- if ((save_file = fopen(buff, "w")) == NULL)
- {
- errprintf("Could not create file");
- world_changed++;
- break;
- }
- nsaved = 0;
- do_for_all_selected(save_it);
- fclose(save_file);
- save_file = NULL;
- screen_refresh(current_camera);
- sprintf(buff, "Saved %d object%s", nselected, (nselected > 1) ? "s" : "");
- popmsg(buff);
- get_response(1);
- world_changed++;
- fclose(out);
- break;
- case 'I':
- {
- seg_info(0);
- get_response(1);
- break;
- }
- case 'D':
- restore_screen();
- if(check_obj()) break;
- sprintf(buff, "Delete %d object%s! Are you sure?",
- nselected, (nselected > 1) ? "s" : "");
- popmsg(buff);
- i = get_response(1);
- if (toupper(i) != 'Y') break;
- restore_screen();
- do_for_all_selected(zap_obj);
- world_changed++;
- break;
- case 'U':
- do_for_all_selected(unhighlight_object);
- world_changed++;
- break;
- case 'F':
- if(check_obj()) break;
- do_for_all_selected(first_it);
- world_changed++;
- break;
- case 'N':
- if(check_obj()) break;
- do_for_all_selected(next_it);
- world_changed++;
- break;
- default: break;
- }
- restore_screen();
- return 0;
- }
-
-
- /************** FIGURE MENU *************/
-
- static int fig_menu(void)
- {
- char buff[100], *p;
- FILE *in, *out;
- char c, d;
- long x, y, z;
- int mx, my;
-
- save_screen();
- switch (menu(figmenu))
- {
- case 'L':
- askfor("Figure file to read? ", buff, 15);
- if (buff[0] == '\0') break;
- add_ext(buff,"fig");
- if ((in = fopen(buff, "r")) == NULL)
- {
- errprintf("Could not open figure file");
- }
- else
- {
- OBJECT *obj;
- POSE p = DONTCARE_POSE;
-
- obj = load_figure_as_object(in, default_objlist, NULL, 0, 1, 1, 1);
- if (!obj)
- {
- errprintf("%s",seg_error(NULL));
- world_changed++;
- }
- else
- {
- add_objlist_to_world(default_objlist);
- mxosize = 0;
- do_for_visible_child_objects(obj, maxsize_it);
- camera_point_ahead(current_camera, 1000+mxosize, &p.x, &p.y, &p.z);
- set_object_pose(obj, &p);
- update_object(obj);
- }
- }
- world_changed++;
- break;
- case 'I':
- seg_info(1);
- get_response(1);
- break;
- case 'S':
- if(check_moveobj()) break;
- do_for_visible_related_objects(last_figure, highlight_object); /* and down again */
- break;
- case 'U':
- do_for_all_selected_moveable(unhighlight_object);
- world_changed++;
- break;
- case 'H':
- if(check_moveobj()) break;
- screen_refresh(current_camera);
- do_for_all_selected_moveable(hack_it);
- world_changed++;
- break;
- case 'J':
- if (check_moveobj()) break;
- if (!can_point_2D()) break;
- if (!manip_2D_avail) break;
- popmsg("Click on new parent");
- tdelay(500);
- restore_screen();
- newparent = NULL;
- while(!newparent)
- {
- if(kbhit()) break;
- newparent = move_and_find_object_2D(cursor_device, NULL);
- if(!is_object_moveable(newparent)) newparent = NULL;
- }
- if(!newparent) break;
- do_for_all_selected_moveable(join_it);
- world_changed++;
- break;
- case 'A':
- if(check_moveobj()) break;
- connect_body(last_figure);
- world_changed++;
- break;
- case 'D':
- disconnect_body ();
- if(!flymode)
- {
- body_pose->rz = 0;
- }
- world_changed++;
- break;
- default:
- break;
- }
- restore_screen();
- return 0;
- }
-
-
-
- /***************** DISPLAY OPTIONS MENU ***************/
-
- static int disp_options(void)
- {
- char buff[20];
-
- switch(menu(optmenu))
- {
- case 'M':
- animatemode = !animatemode;
- break;
- case 'S':
- do_screen_clear = !do_screen_clear;
- popmsg(do_screen_clear ? "Will clear" : "Won't clear");
- set_horizon(1,NULL,0);
- tdelay(600); // so menu is erased
- restore_screen();
- if (!do_screen_clear) set_horizon(0,NULL,0);
- else
- {
- if (do_horizon) set_horizon(2,NULL,0);
- else set_horizon(1,NULL,0);
- }
- display_changed++;
- break;
- case 'D':
- {
- int s = (get_light_type(light1)==POINT_LIGHT) ? SPOT_LIGHT : POINT_LIGHT;
- set_light_type(light1, s);
- popmsg(s==SPOT_LIGHT ? "Spotlight" : "Point Source");
- tdelay(600);
- world_changed++;
- break;
- }
- case 'H':
- do_horizon = !do_horizon;
- if (do_horizon) set_horizon(2,NULL,0);
- else set_horizon(1,NULL,0);
- popmsg(do_horizon ? "Horizon" : "No Horizon");
- tdelay(600);
- display_changed++;
- break;
- case 'A':
- askfor("Ambient light: ", buff, 15);
- set_light_intensity(amb_light, atoi(buff));
- world_changed++;
- break;
- case 'P':
- show_location = !show_location;
- reset_screens();
- display_changed++;
- break;
- case 'C':
- show_compass = !show_compass;
- reset_screens();
- display_changed++;
- break;
- case 'F':
- show_framerate = !show_framerate;
- reset_screens();
- display_changed++;
- break;
- default:
- break;
- }
- restore_screen();
- return 0;
- }
-
-
- /*************** PAINTING MENU OPERATIONS **********/
-
- static unsigned stype[] = { 0, 0x1000, 0x2000, 0x3000 };
-
- static unsigned paint = 1;
- static unsigned surface = 0x1000;
- static unsigned paintcolor = 1;
-
- static void surf_it(OBJECT *obj)
- {
- masked_recolor_object_surface(obj, surface, 0x3000, 0);
- }
-
- static void color_it(OBJECT *obj)
- {
- masked_recolor_object_surface(obj, paint, 0x3FFF, 0);
- }
-
-
- static unsigned int get_surface(void)
- {
- save_screen();
- switch (menu(surfmenu))
- {
- case 'A':
- surface = stype[0];
- break;
- case 'C':
- surface = stype[1];
- break;
- case 'M':
- surface = stype[2];
- break;
- case 'G':
- surface = stype[3];
- break;
- default:
- return 1;
- }
- if (surface == 0) paint = paintcolor;
- else paint = (surface | ((paintcolor << 4) & 0x0FF0) + 10); /* hue, brightness *16 */
- restore_screen();
- while (bioskey(1)) bioskey(0); /* flush keyboard buffer */
- return 0;
- }
-
-
- static int painting(void)
- {
- int x, y, c, i;
- unsigned buttons;
- char buff[100];
-
- if (!can_point_2D()) return 3;
- save_screen();
-
- switch (menu(paintmenu))
- {
- case 'S':/* select surface */
- get_surface();
- break;
-
- case 'C':/* select color */
- if (!can_point_2D()) break;
- if (!manip_2D_avail) break;
- disp_palette();
- do {
- move_till_click(cursor_device, 1, &x, &y);
- }
- while (y>128 || x>160);
- paintcolor = 16*(y/8) + x/10;
- if (surface == 0)
- paint = paintcolor;
- else
- paint = (surface | ((paintcolor << 4) & 0x0FF0) + 10); /* hue, brightness *16 */
- world_changed++;
- break;
-
- case 'G':
- restore_screen();
- while (1)
- {
- int poly;
- WORD buttons;
- OBJECT *obj;
-
- if (kbhit()) break;
- obj = move_and_find_object_2D(cursor_device, &buttons);
- if (obj)
- {
- poly = screen_found_poly();
- if(buttons & 0x01)
- {
- get_poly_info(obj, poly, &c, NULL);
- c &= 0x7FFF;
- sprintf(buff,"Poly Color: 0x%04x", c);
- save_screen();
- popmsg(buff);
- while(1)
- {
- int button;
- mouse_read(cursor_device,NULL,NULL,&button);
- if(!button) break;
- }
- restore_screen();
- surface = c & 0x7000;
- paintcolor = c & 0xFFF;
- paint = c;
- }
- else break;
- }
- }
- while (kbhit()) getch();
- world_changed++;
- break;
-
- case 'P':
- restore_screen();
- while (1)
- {
- int poly;
- WORD buttons;
- OBJECT *obj;
-
- if (kbhit()) break;
- obj = move_and_find_object_2D(cursor_device, &buttons);
- if (obj)
- {
- poly = screen_found_poly();
- if(buttons & 0x01)
- {
- set_poly_color(obj, poly, paint);
- screen_refresh(current_camera);
- }
- else if (buttons & 0x02)
- {
- get_poly_info(obj, poly, &c, NULL);
- c &= 0x7FFF;
- sprintf(buff,"Poly Color: 0x%04x", c);
- save_screen();
- popmsg(buff);
- while(1)
- {
- int button;
- mouse_read(cursor_device,NULL,NULL,&button);
- if(!button) break;
- }
- restore_screen();
- surface = c & 0x7000;
- paintcolor = c & 0xFFF;
- paint = c;
- }
- }
- }
- while (kbhit()) getch();
- world_changed++;
- break;
-
- case 'R':
- restore_screen();
- if(get_surface()) break;
- do_for_all_selected(surf_it);
- world_changed++;
- break;
-
- case 'A':
- do_for_all_selected(color_it);
- world_changed++;
- break;
- default:
- break;
- }
- restore_screen();
- return 0;
- }
-
-
- /****************** MAIN MENU *************/
-
- static int main_menu(void)
- {
- switch(menu(mainmenu))
- {
- case 'Q':
- process_a_key('Q');
- break;
- case 'I':
- process_a_key('I');
- break;
- case 'H':
- process_a_key('H');
- break;
- case 'O':
- process_a_key('O');
- break;
- case 'P':
- process_a_key('P');
- break;
- case 'F':
- process_a_key('F');
- break;
- case 'M':
- process_a_key('M');
- break;
- case 'D':
- disp_options();
- break;
- case 'V':
- view_menu();
- break;
- default:
- break;
- }
- restore_screen();
- return 0;
- }
-
-
-
-
- /******************* SPINNING VIEW COMPUTE **************/
-
-
- static l_x = 1000, l_y = 15000, l_z = -5000; /* light source */
-
- long center_d = 10000;
- long center_x = 0;
- long center_y = 0;
- long center_z = 0;
- long latitude = 0;
- long longitude = 0;
- long center_roll = 0;
-
- static long light_d = 1000000;
-
- void spin_mode_compute() /* for spin mode: recompute viewpoint based on */
- { /* view angle and distance so object centered */
- MATRIX m,n;
- POSE p = DONTCARE_POSE;
-
- long x = 0;
- long y = 0;
- long z = -center_d;
-
- latitude = body_pose->ry; // angles of vision
- longitude = body_pose->rx;
- center_roll = body_pose->rz;
-
- std_matrix(n,longitude,latitude,center_roll,0,0,0);
- matrix_point(n,&x,&y,&z);
- body_pose->x = x + center_x; // shift to distance from view center
- body_pose->y = y + center_y;
- body_pose->z = z + center_z;
-
- if(get_light_type(light1)==POINT_LIGHT) // some attempt for
- { // interesting lighting
- x = l_x;
- y = l_y;
- z = l_z;
- matrix_point(n,&x,&y,&z);
- p.x = x;
- p.y = x;
- p.z = x;
- position_pointlight(light1, &p);
- }
- else
- {
- p.rx = longitude + float2angle(45);
- p.ry = latitude + float2angle(45);
- p.rz = 0;
- rotate_spotlight(light1, &p);
- }
- }
-
-
- /********************** KEY INTERPERTER *****************/
-
- void view_menu(void), mouse_menu(void), stereo_info(void);
-
- extern BOOL process_motion_keys(unsigned key);
-
- BOOL process_display_keys(unsigned c) // processes and display setup keys
- {
- int i, j;
-
- switch (c)
- {
- case CTRLLEFT:
- i = +1;
- goto set_shift;
- case CTRLRIGHT:
- i = -1;
- set_shift:
- if (current_camera->stereo->window[LEFT_EYE].orientation&XFLIP)
- current_camera->stereo->window[LEFT_EYE].xoff += i;
- else
- current_camera->stereo->window[LEFT_EYE].xoff -= i;
-
- if (current_camera->stereo->window[RIGHT_EYE].orientation&XFLIP)
- current_camera->stereo->window[RIGHT_EYE].xoff -= i;
- else
- current_camera->stereo->window[RIGHT_EYE].xoff += i;
-
- compute_camera_factors(current_camera);
- display_changed++;
- break;
- case '+':
- if (stereo_type == MONOSCOPIC)
- {
- SCALE z = get_camera_zoom(current_camera);
- z *= 1.1;
- if(z<65536L*0.5) z = 65536L*0.5;
- if(z>65536L*16.0) z = 65536L*16.0;
- set_camera_zoom(current_camera,z);
- }
- else
- {
- if(current_camera->stereo->phys_screen_dist>30)
- current_camera->stereo->phys_screen_dist *= 1.05;
- else current_camera->stereo->phys_screen_dist *= 1.25;
- }
- compute_camera_factors(current_camera);
- display_changed++;
- break;
- case '-':
- if (stereo_type == MONOSCOPIC)
- {
- SCALE z = get_camera_zoom(current_camera);
- z /= 1.1;
- if(z<65536L*0.5) z = 65536L*0.5;
- if(z>65536L*16.0) z = 65536L*16.0;
- set_camera_zoom(current_camera,z);
- compute_camera_factors(current_camera);
- display_changed++;
- break;
- }
- else
- {
- current_camera->stereo->phys_screen_dist /= 1.05;
- if(current_camera->stereo->phys_screen_dist<5)
- current_camera->stereo->phys_screen_dist = 5;
- }
- compute_camera_factors(current_camera);
- display_changed++;
- break;
- case '@':
- if (stereo_type != MONOSCOPIC)
- {
- current_camera->stereo->phys_eye_spacing /= 1.05;
- if(current_camera->stereo->phys_eye_spacing<5)
- current_camera->stereo->phys_eye_spacing = 5;
- compute_camera_factors(current_camera);
- display_changed++;
- }
- break;
- case '!':
- if (stereo_type != MONOSCOPIC)
- {
- if(current_camera->stereo->phys_eye_spacing>30)
- current_camera->stereo->phys_eye_spacing *= 1.05;
- else
- current_camera->stereo->phys_eye_spacing *= 1.25;
- compute_camera_factors(current_camera);
- display_changed++;
- }
- break;
- default:
- return FALSE;
- }
- return TRUE;
- }
-
-
- BOOL process_info_keys(unsigned c) // processes daata-display keys
- {
- int i, j;
-
- switch (c)
- {
- case 'H':
- save_screen();
- poptext(helptext);
- get_response(1);
- restore_screen();
- break;
- case 'I':
- {
- POSE p;
- get_camera_worldpose(current_camera,&p);
- save_screen();
- disp_status(&p);
- get_response(1);
- restore_screen();
- break;
- }
- case '$':
- stereo_info();
- break;
- case 'C':
- save_screen();
- disp_palette();
- get_response(1);
- restore_screen();
- break;
- default:
- return FALSE;
- }
- return TRUE;
- }
-
-
- TELEPORT *fnkeyposn[10] =
- { NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL };
- TELEPORT *fnkeyhome[10];
-
- WORD current_teleport = 0; // where to go home to
-
- extern OBJECT *body_vehicle_object;
-
-
- BOOL process_teleport_keys(unsigned c) // processes teleport and home keys
- {
- int i, j;
-
- switch (c)
- {
- case F1:
- case F2:
- case F3:
- case F4:
- case F5:
- case F6:
- case F7:
- case F8:
- case F9:
- case F10:
- {
- i = (c- F1) >> 8;
- if(i==current_teleport) break;
- // record current position for return
- teleport_set_here(fnkeyposn[current_teleport], body_pose);
- teleport_set_vehicle(fnkeyposn[current_teleport],
- body_vehicle_object,NULL);
- current_teleport = i; // set home number
- if(fnkeyposn[i])
- {
- teleport_to(fnkeyposn[i]);
- }
- else
- {
- fnkeyposn[i] = create_teleport(); // records current state
- fnkeyhome[i] = create_teleport();
- }
- position_changed++;
- break;
- }
- case HOME:
- if(fnkeyposn[current_teleport])
- {
- teleport_to(fnkeyhome[current_teleport]);
- }
- position_changed++;
- break;
-
- default:
- return FALSE;
- }
- return TRUE;
- }
-
-
- BOOL process_system_keys(unsigned c) // processes quit, etc
- {
- int i, j;
-
- switch (c)
- {
- case 'A':
- animatemode = !animatemode;
- break;
- case TAB:
- if(animatemode==0) animatemode = -1;
- break;
-
- case '^':
- save_pcx_file();
- break;
-
- case 'Q':
- case ESC:
- popmsg("Really quit?");
- i = get_response(1);
- if (toupper(i)=='Y') running = 0;
- else restore_screen();
- break;
- default:
- return FALSE;
- }
- return TRUE;
- }
-
- extern int mouse_nav;
-
- static int movemults[] = { 1,2,3,5,7,10,13,17,22,28}; // speed, angles
- static int angmults[] = { 1,1,1,1,2,2,2,3,4,5}; // 0-9 scale factors
-
-
- BOOL process_extmove_keys(unsigned c) // processes daata-display keys
- {
- int i, j;
-
- switch (c)
- {
-
- case '*': /* level view */
- body_pose->rx = body_pose->rz = 0;
- display_changed++;
- break;
-
- case 'U':
- body_pose->ry += 180*65536L;
- position_changed++;
- break;
-
- case '0':
- sstepsize = movemults[9];
- astepsize = angmults[9];
- break;
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- sstepsize = movemults[c - '1'];
- astepsize = angmults[c - '1'];
- break;
-
- case 'S':
- if(spinmode) spinmode = 0;
- else
- {
- OBJECT *newobj = NULL;
- float dist;
-
- save_screen();
- if (can_point_2D() && manip_2D_avail)
- {
- restore_screen();
- popmsg("Click on object to spin about");
- tdelay(500);
- restore_screen();
- while(!newobj)
- {
- newobj = move_and_find_object_2D(cursor_device,NULL);
- if(kbhit()) break;
- }
- if(!newobj) break;
- get_object_bounds(newobj, ¢er_x, ¢er_y, ¢er_z);
- }
- center_d = magnitude32(center_x - body_pose->x,
- center_y - body_pose->y,
- center_z - body_pose->z );
- spinmode = 1;
- }
- break;
-
- case 'J':
- mouse_nav = !mouse_nav; // toggle mouse joy
- if(manip_2D_avail)
- cursor_enable(!mouse_nav); // cursor on/off
- break;
-
-
- default:
- return FALSE;
- }
- return TRUE;
- }
-
-
- BOOL process_menu_keys(unsigned c) // processes menu-entry keys
- {
- int i, j;
-
- switch (c)
- {
- case 'X':
- main_menu();
- break;
- case 'D':
- disp_options();
- restore_screen();
- break;
- case 'O':
- obj_menu();
- break;
- case 'F':
- fig_menu();
- break;
- case 'P':
- painting();
- break;
- case 'M':
- mouse_menu();
- break;
- case 'V':
- view_menu();
- break;
- default:
- return FALSE;
- }
- return TRUE;
- }
-
-
- /************ API KEY HANDLER **************/
-
- void process_a_key(unsigned c) // processes key <c>
- {
- int i, j;
-
- if(c<0x7f)
- if(isalpha(c))
- c = toupper(c);
-
- if(process_motion_keys(c)) return;
- if(process_display_keys(c)) return;
- if(process_info_keys(c)) return;
- if(process_teleport_keys(c)) return;
- if(process_system_keys(c)) return;
- if(process_extmove_keys(c)) return;
- if(process_menu_keys(c)) return;
- }
-
-
- void key_process() // reads, processes keys
- {
- unsigned c;
-
- if (!bioskey(1)) return;
- c = getkey(); // read a key
- while(bioskey(1)) getkey(); // dump others
-
- process_a_key(c);
- }
-
-
- /************ API JOYSTICK HANDLER **************/
-
-
- void joystick_process()
- {
- if(do_joy_navigate(body_pose,
- spinmode, spacestep*sstepsize, astepsize*anglestep, flymode))
- position_changed ++;
-
- if (position_changed && spinmode) // SPECIAL: spin mode move xlat
- spin_mode_compute();
- }
-
-